package com.tao.mytestsocket

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.tao.mytestsocket.http.MsgCache
import com.tao.utilslib.log.LogUtil
import com.tao.utilslib.net.HttpRequestUtil
import com.tao.utilslib.net.HttpRequestUtil.OnReques
import com.yanzhenjie.andserver.AndServer
import com.yanzhenjie.andserver.Server
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit


/**
 *reate by tao on{DATE}
 */
open class HttpTest(open var act: ILog) {
    open val tag = "http服务"
    open var serverIp: String = ""
    open var serverPort: Int = 0
    open var localPort = 0
    open var send_loop = false
    var andServer: Server? = null
    val executors = Executors.newSingleThreadExecutor()
    val msgRev = MyMsgRev()
    val timerList = CopyOnWriteArrayList<TimerData>()

    init {
        satrtTimer(1000)
    }

    private fun satrtTimer(time: Int) {
        val timer = Timer()
        timer.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                timerList.forEach {
                    if (System.currentTimeMillis() - it.start > it.time) {

                        act.appendText(
                            "数据响应超时 消息ID:${it.msgId}  消息内容：{${
                                if (it.msg?.length!! > 100) {
                                    "${it.msg?.subSequence(0, 100)} ...."
                                } else it.msg
                            }}"
                        )
                        timerList.remove(it)
                    }
                }


            }
        }, 0, time.toLong())


    }

    open fun switchHttp(open: Boolean): Boolean {
        if (open) {
            if (checkLocalPort()) return false
            open()
        } else {
            close()
        }
        return true
    }

    fun checkLocalPort(): Boolean {
        if (localPort <= 0) {
            act.appendText("$tag  远程端口 ${localPort} 不正确")
            return true
        }
        return false
    }

    open fun open() {
        close()
        synchronized(this) {
            andServer = AndServer.webServer(act.getContext())
                .port(localPort)
                .timeout(10, TimeUnit.SECONDS)
                .inetAddress(NetUtils.getLocalIPAddress())
                .listener(object : Server.ServerListener {
                    override fun onStarted() {
                        act.appendText("$tag 端口:$localPort  服务开启 ")
                        registerMsgRev()
                    }

                    override fun onStopped() {
                        act.appendText("$tag 端口:$localPort  服务停止 ")

                    }

                    override fun onException(e: java.lang.Exception?) {
                        act.appendText("$tag 端口:$localPort  服务异常 ${e?.toString()}")
                        e?.printStackTrace()

                    }
                })
                .build()
// startup the server.
            andServer?.startup()


        }
    }

    private fun registerMsgRev() {
        val intentFilter = IntentFilter()
        intentFilter.addAction(MSG_REV_)
        act.getContext().registerReceiver(msgRev, intentFilter)
    }

    inner class MyMsgRev : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent?.let {
                val hash = it.getIntExtra("msg", 0)
                val tackMsg = MsgCache.tackMsg(hash)
                act.appendText(
                    "$tag   收到请求 数据长度${tackMsg?.length} 数据内容{${tackMsg?.length} 数据： ${
                        if (tackMsg?.length!! > 100) {
                            "${tackMsg.subSequence(0, 100)} ..."
                        } else {
                            tackMsg
                        }
                    } "
                )
            }

        }
    }


    open fun close() {
        synchronized(this) {
            try {
                Thread.sleep(50)
            } catch (e: Exception) {
            }
            andServer?.shutdown()
            try {
                Thread.sleep(50)
            } catch (e: Exception) {
            }
            andServer?.let {
                act.appendText("$tag  端口:$localPort  关闭${if (it.isRunning) "失败" else "成功"}")
                andServer = null
                try {
                    act.getContext().unregisterReceiver(msgRev)
                } catch (e: Exception) {
                }
            }


        }
    }

    var msgID = 0
    var loopIng = false
    open fun send(msg: String) {
        if (ckSend(msg)) return
        if (loopIng) return
        executors.execute {
            try {
                do {
                    if (send_loop) {
                        loopIng = true
                    }
                    val parame = mutableMapOf<String, String>()
                    parame["msg"] =
                        "消息来自：" + NetUtils.getLocalIPAddress().hostName + " 消息ID：${msgID++}  \n  消息内容：{${msg} }"
                    parame["msgId"] = "${msgID - 1}"
                    act.appendText(
                        "$tag  发送数据：目标：$serverIp:$serverPort msgId:${msgID - 1}  数据长度 ${parame["msg"]?.length} 数据：${
                            if (parame["msg"]?.length!! > 100) {
                                "${parame["msg"]?.subSequence(0, 100)} ...."
                            } else parame["msg"]
                        }"
                    )
                    pushTimer(TimerData(parame["msg"]!!, parame["msgId"]!!))
                    HttpRequestUtil.postForm(
                        "http://${serverIp}:${serverPort}/msg",
                        parame,
                        object : OnReques<Any?>(HttpRequestUtil.RequestType.string) {
                            override fun onSuccessString(str: String?) {
                                removeTimerData(parame["msgId"]!!)

                                act.appendText(
                                    "$tag   请求成功 数据长度${str?.length} 数据内容: ${
                                        if (str?.length!! > 100) {
                                            "${str.subSequence(0, 100)} ..."
                                        } else {
                                            str
                                        }
                                    } "
                                )

                            }

                            override fun onFailed(msg: String?) {
                                act.appendText("$tag   请求失败： ${msg}  ")
                                removeTimerData(parame["msgId"]!!)

                            }
                        })

                    try {
                        Thread.sleep(if (msg.length > 1024) (msg.toByteArray().size / 500).toLong() else 100)
                    } catch (e: Exception) {
                    }

                } while (send_loop)
            } finally {
                loopIng = false
            }

        }
    }

    fun removeTimerData(msgId: String) {
        timerList.forEach {
            if (msgId.contains(it.msgId)) {
                timerList.remove(it)
                LogUtil.e("移除消息 id：${msgId}")
            }
        }

    }

    fun pushTimer(timerData: TimerData) {
        timerList.add(timerData)
    }

    class TimerData {
        var start = System.currentTimeMillis()
        var time = 5 * 1000
        var hashCode = 0
        var msg = ""
        var msgId = ""

        constructor(msg: String, msgId: String) {
            this.msg = msg
            this.msgId = msgId
            hashCode = msg.hashCode()
        }
    }

    fun ckSend(msg: String): Boolean {
        if (msg.isNullOrEmpty()) {
            act.appendText("$tag  发送的消息为空")
            return true
        }
        if (serverPort <= 0) {
            act.appendText("$tag  远程端口 ${serverPort} 不正确")
            return true

        }
        if (serverIp.isNullOrEmpty()) {
            act.appendText("$tag  远程地址 ${serverIp} 不正确")
            return true
        }
        return false
    }

    companion object {
        @JvmStatic
        val MSG_REV_ = "MSG_REV_"
    }

}